home *** CD-ROM | disk | FTP | other *** search
- Path: rain.fr!world-net!usenet
- From: Frederic LACHASSE <lachass@worldnet.fr>
- Newsgroups: comp.lang.c++
- Subject: Re: Urgent help - pointers to functions
- Date: Tue, 02 Apr 1996 19:37:33 +0000
- Organization: World-Net information exchange, Internet provider.
- Message-ID: <VA.00000075.0004d66b@fred>
- References: <internews46B6FAA4E6@argonet.co.uk>
- Reply-To: lachass@worldnet.fr
- NNTP-Posting-Host: pm6-122.sct.fr
- X-Newsreader: Virtual Access by Ashmount Research Ltd, http://www.ashmount.com
-
- In article <internews46B6FAA4E6@argonet.co.uk>, Charlotte Tomlinson
- <eeyore@argonet.co.uk> wrote:
- >
- > I have implemented a template doubly linked list, the backbones of which
- > is as follows:
- >
- [snip]
- >
- >
- > Then I have a class, called fuzzyset, which uses this dll as a container
- > for fuzzyel instances:
- >
- > //fuzzyset.h
- > /*snip*/
- >
- > class fuzzyset {
- > private:
- > dllist<fuzzyel> members;
- >
- > public:
- > fuzzyset() {}
- > fuzzyset(const fuzzyset&);
- > fuzzyset(const fuzzyel&);
- > /*other functions and operators*/
- > };
- >
- >
- > What I would like to do is, within dllist, to implement a function forEach
- > that take a pointer to a function as one argument, and somehow the rest of
- > the arguments required by that function, and carries that function out
- > over each element of the list.
- >
- > One example of what I need to do is as follows. In my main program (where
- > fuzzyset is included), I need to be able to call a function that prints
- > every element of the 'members' list in any called instance of a fuzzyset.
- >
- > I need the forEach function to be quite generic, because I will have other
- > uses for it later.
- >
-
- The most generic way of providing a callback function is using a pointer to a
- base class with a virtual member function:
-
- template <class T>
- class CallbackFor
- {
- public:
- virtual void operator()(T const&) = 0;
- virtual ~CallbackFor() {}
- };
-
- usage will be:
-
- void fuzzyset::applyForEach(CallbackFor<fuzzyel>* cb)
- {
- for (...)
- {
- (*cb)(elem);
- }
-
- delete cb;
- }
-
- Then you can do anything you like. The most common derivations are:
- - calling functions with preliminary fixed parameters: (example use 2 fixed
- parms but is easy to extend to any number)
-
- template <class T, class T1, class T2>
- class CallbackFn2 : public CallbackFor<T>
- {
- public:
- typedef void (*pfn)(T1, T2, T const&);
- private:
- pfn fn;
- T1 arg1;
- T2 arg2;
- public:
- CallbackFn2(pfn f, T1 a1, T2 a2)
- : fn(f), arg1(a1), arg2(a2) {}
- void operator()(T const&);
- };
-
- template <class T, class T1, class T2>
- void CallbackFn2<T,T1,T2>::operator()(T const& arg)
- {
- fn(arg1, arg2, arg);
- }
-
- template <class T, class T1, class T2>
- CallbackFor<T>* callback(CallbackFn2<T,T1,T2>::pfn fn, T1 arg1, T2 arg2)
- {
- return new CallbackFn2<T,T1,T2>(fn, arg1, arg2);
- }
-
- - calling a non-static member function of a class
- template <class T, class TT>
- class CallbackMember : public CallbackFor<T>
- {
- public:
- typedef void (TT::*pfn)(T const&);
- private:
- pfn fn;
- TT* obj;
- public:
- CallbackMember(pfn f, TT* o)
- : fn(f), obj(o) {}
- void operator()(T const&);
- };
-
- template <class T, class TT>
- void CallbackMember<T,TT>::operator()(T const& arg)
- {
- obj->*fn(arg);
- }
-
- template <class T, class TT>
- CallbackFor<T>* callback(CallbackMember<T,TT>::pfn fn, TT* obj)
- {
- return new CallbackMember<T,TT>(fn, obj);
- }
-
-
- Usage are:
-
- void doFn(int, char*, fuzzyel const&);
- class doMbr
- {
- public:
- do(fuzzyel const&);
- };
-
- fuzzyset set;
- doMbr action;
- set.applyForEach(callback(doFn, 1, "coucou"));
- set.applyForEach(callback(&doMbr::do, &action));
-
- Except for typo, this should work.
-
- I hope this'll help.
-
- Frederic LACHASSE (ECP 86)
- CompuServe: 100530,2005
- Internet: lachass@worldnet.fr
-
-